package com.ruoyi.smart.mqtt;

import java.util.Arrays;

public class MqttTopicMatcher {

    public static boolean matches(String filter, String topic) {
        if (filter == null || topic == null) {
            return false;
        }

        // 快速路径：完全相等
        if (filter.equals(topic)) {
            return true;
        }

        // 特殊处理：以$开头的主题只能匹配以$开头的过滤器
        if (topic.startsWith("$") != filter.startsWith("$")) {
            return false;
        }

        String[] filterParts = filter.split("/");
        String[] topicParts = topic.split("/");

        int filterIndex = 0;
        int topicIndex = 0;

        while (filterIndex < filterParts.length && topicIndex < topicParts.length) {
            String filterPart = filterParts[filterIndex];
            String topicPart = topicParts[topicIndex];

            // 处理多级通配符#
            if ("#".equals(filterPart)) {
                // #必须是过滤器的最后一部分
                if (filterIndex != filterParts.length - 1) {
                    return false;
                }
                // #匹配当前级别和所有后续级别
                return true;
            }

            // 单级通配符+匹配任意非空部分
            if ("+".equals(filterPart)) {
                if (topicPart.isEmpty()) {
                    return false; // +不能匹配空的部分
                }
            } else if (!filterPart.equals(topicPart)) {
                // 精确匹配失败
                return false;
            }

            // 移动到下一级
            filterIndex++;
            topicIndex++;
        }

        // 检查是否同时到达末尾
        boolean filterDone = filterIndex == filterParts.length;
        boolean topicDone = topicIndex == topicParts.length;

        // 如果过滤器用完但主题还有剩余，不匹配
        // 如果主题用完但过滤器还有剩余（且不是#），不匹配
        return filterDone && topicDone;
    }

    public static void main(String[] args) {
        String filter = "$SYS/brokers/+/clients/+/+";
        String topic = "$SYS/brokers/emqx@127.0.0.1/clients/bxy2000/disconnected";

        boolean result = matches(filter, topic);
        System.out.println("过滤器: " + filter);
        System.out.println("主题: " + topic);
        System.out.println("匹配结果: " + result);

        // 测试其他示例
        System.out.println("\n其他测试:");
        System.out.println(matches("sport/tennis/player1/+", "sport/tennis/player1/ranking")); // true
        System.out.println(matches("sport/tennis/player1/#", "sport/tennis/player1/")); // true
        System.out.println(matches("sport/tennis/+/ranking", "sport/tennis/player1/ranking")); // true
        System.out.println(matches("sport/tennis/+/ranking", "sport/tennis/player1/score")); // false
    }

}
